/*
 * Copyright (c) Informatica Corporation 1994 - 2011
 * All Rights Reserved.
 * This Software is protected by U.S. Patent Numbers 5,794,246; 6,014,670; 
 * 6,016,501; 6,029,178; 6,032,158; 6,035,307; 6,044,374; 6,092,086; 6,208,990; 
 * 6,339,775; 6,640,226; 6,789,096; 6,820,077; 6,823,373; 6,850,947; 6,895,471; 
 * 7,117,215; 7,162,643; 7,254,590; 7,281,001; 7,421,458;7,496,588; 7,523,121; 7,584,422;  
 * 7,720,842; 7,721,270; and 7,774,791, international Patents and other Patents Pending.
 *
 * This is a read only file generated by PowerCenter client tools.
 * This contains the user snippets code as well as other generated code.
 * User snippet code is embedded in this file within appropriate 
 * comments.
 */
package dvo.infact.test;

import com.informatica.powercenter.sdk.server.IBufferInit;
import com.informatica.powercenter.sdk.server.IInputBuffer;
import com.informatica.powercenter.sdk.server.IOutputBuffer;
import com.informatica.powercenter.sdk.repository.IGroup;
import com.informatica.powercenter.sdk.repository.IField;
import com.informatica.powercenter.sdk.SDKException;
import com.informatica.powercenter.sdk.server.ELogMsgLevel;
import com.informatica.powercenter.sdk.server.DataTruncatedException;
import com.informatica.powercenter.server.jtx.JTXFatalException;
import com.informatica.powercenter.server.jtx.JTXPartitionDriverImplFixed;
import com.informatica.powercenter.server.jtx.JTXUtils;
import java.util.List;

// Start of 'Import Package' snippet.
// ToDo: Enter the Java packages to be  imported here
// For example, if you want to use Hashtable in any of the snippets, import the Hashtable // as shown below:
// 
// import java.util.Hashtable;
import java.lang.management.ManagementFactory;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;

class CacheClient {

    InetAddress host;
    Socket socket = null;
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;

    CacheClient(JTXPartitionDriverImplGen jtx) {
        try {
            host = InetAddress.getLocalHost();
            socket = new Socket(host.getHostName(), 19999);
            //write to socket using ObjectOutputStream
            oos = new ObjectOutputStream(socket.getOutputStream());
            ois = new ObjectInputStream(socket.getInputStream());
            
            
        } catch (Exception ex) {
            
        }
    }

    public String getDesc(String data) throws IOException, ClassNotFoundException {


        //System.out.println("Sending request to Socket Server");
        oos.writeObject(data);
        oos.flush();
        //read the server response message

        String message = (String) ois.readObject();


        return message;
    }

    public void close() {
//close resources
        try {
            getDesc("exit");
            ois.close();
            oos.close();
        } catch (Exception ex) {
        }

    }
}
// End of 'Import Package' snippet.

/**
 * This class is a partition level class, which encapsulates the logic specified
 * by the user in various Java Transformation code snippets. One instance of
 * this class will be used to serve each partition.
 */
public class JTXPartitionDriverImplGen extends JTXPartitionDriverImplFixed {

    // Start of 'Helper code' snippet.
    // ToDo: Declare static and non-static  partition level variables and functions here
    // For example,
    // 
    // static int countNullRows;            // counts the number of output rows across all partitions containing null values
    // int partCountNullRows;               // counts the number of output rows in this partition containing null values
    // 
    // static Object lock = new Object();   // lock to synchronize countNullRows
    CacheClient cacheClient = new CacheClient(this);
    // End of 'Helper code' snippet.
    private StringBuffer strBuf = new StringBuffer();
    private String DESC;
    public void logInfoC(String msg){
        logInfo(msg);
    }
    /**
     * This function is called by PowerCenter engine once per session for a
     * given transformation partition.
     *
     * @param inBufInit List of objects of IBufferInit for input groups.
     * @param outBufInit List of objects of IBufferInit for output groups.
     */
    public void init(List inBufInits, List outBufInits) throws SDKException {
        IBufferInit inBufInit = (IBufferInit) inBufInits.get(0);
        IBufferInit outBufInit = (IBufferInit) outBufInits.get(0);
        outputBufCap = outBufInit.getCapacity();
        initialize();

        if (isInFldConnected("KEY")) {
            if (JTXUtils.isServerUnicodeMode()) {
                inBufInit.bindColumnDataType(0, IField.JDataType.UNICHAR);
            } else {
                inBufInit.bindColumnDataType(0, IField.JDataType.CHAR);
            }
        }

        if (isInFldConnected("BRANCH_CODE")) {
            if (JTXUtils.isServerUnicodeMode()) {
                inBufInit.bindColumnDataType(1, IField.JDataType.UNICHAR);
            } else {
                inBufInit.bindColumnDataType(1, IField.JDataType.CHAR);
            }
        }

        if (isInFldConnected("PROD_CODE")) {
            if (JTXUtils.isServerUnicodeMode()) {
                inBufInit.bindColumnDataType(2, IField.JDataType.UNICHAR);
            } else {
                inBufInit.bindColumnDataType(2, IField.JDataType.CHAR);
            }
        }

        if (isOutFldProjected("DESC")) {
            if (JTXUtils.isServerUnicodeMode()) {
                outBufInit.bindColumnDataType(0, IField.JDataType.UNICHAR);
            } else {
                outBufInit.bindColumnDataType(0, IField.JDataType.CHAR);
            }
        }


    }

    /**
     * This function is called by PowerCenter engine when data is available for
     * the input group.
     *
     * @param grp Input group on which the data is available.
     * @param inputBuf Input Data buffer corresponding to the group.
     */
    public void execute(IGroup grp, IInputBuffer inputBuf) throws SDKException {
        setInputBuffer(inputBuf);
        resetOutputRowNumber();
        outputBuf = (IOutputBuffer) getOutputBuffers().get(0);
        int numRowsAvailable = inputBuf.getNumRowsAvailable();
        inRowNum = 0;

        Object defaultObj;
        String KEY;
        String BRANCH_CODE;
        String PROD_CODE;

        for (int jtx_row_counter = 1; jtx_row_counter <= numRowsAvailable; jtx_row_counter++) {
            try {

                DESC = null;

                defaultObj = getOutFldDefault("DESC");
                if (defaultObj != null) {
                    DESC = (String) defaultObj;
                }


                KEY = null;
                BRANCH_CODE = null;
                PROD_CODE = null;


                if (isInFldConnected("KEY") && !inputBuf.isNull(inRowNum, 0)) {
                    strBuf.setLength(0);
                    inputBuf.getStringBuffer(inRowNum, 0, strBuf);
                    KEY = strBuf.toString();
                }

                if (isInFldConnected("BRANCH_CODE") && !inputBuf.isNull(inRowNum, 1)) {
                    strBuf.setLength(0);
                    inputBuf.getStringBuffer(inRowNum, 1, strBuf);
                    BRANCH_CODE = strBuf.toString();
                }

                if (isInFldConnected("PROD_CODE") && !inputBuf.isNull(inRowNum, 2)) {
                    strBuf.setLength(0);
                    inputBuf.getStringBuffer(inRowNum, 2, strBuf);
                    PROD_CODE = strBuf.toString();
                }

                if (isVerbose) {
                    utilsServer.logMsg(ELogMsgLevel.INFO, BEGIN_INPUT_ROW);
                }

                // Start of 'On Input Row' code snippet.
                // ToDo: Enter code to process an input row here.
                // You can access an input column data by referring the input column name
                // You can set an output column data by referring the output column name
                // For example, if
                // input1 and input2 are input ports of type int, and
                // output1 and output2  are output ports of type int
                // then transformation logic can be like as follows:
                // 
                // if(!isNull("input1") && !isNull("input1"))
                // {
                //        output1 = input1 + input2;
                //        output2 = input1 - input2;
                // }
                // else
                // {
                //        setNull("output1");
                //        setNull("output2");
                //        partCountNullRows++;
                //        synchronized(lock)
                //        {
                //            countNullRows++;
                //        }
                // }
                try {
                    DESC = cacheClient.getDesc(KEY + "," + BRANCH_CODE + "," + PROD_CODE);
                } catch (Exception ex) {

                    logError(ex.toString());
                }


                // End of 'On Input Row' code snippet.

                if (isFatalExceptionThrown) {
                    throw new JTXFatalException(fatalMsg);
                }

                if (isVerbose) {
                    utilsServer.logMsg(ELogMsgLevel.INFO, EXIT_INPUT_ROW);
                }

                isGenRowCall = true;
                generateRow();
                isGenRowCall = false;
            } catch (SDKException e) {
                handleException(e);
            }
            prepareForInputRow();
        }
    }

    /**
     * This function is called by PowerCenter engine when no more data is
     * available for the input group.
     *
     * @param iGroup input group for which all the data has been processed.
     */
    public void eofNotification(IGroup group) throws SDKException {
        try {
            if (outputBuf == null) {
                outputBuf = (IOutputBuffer) getOutputBuffers().get(0);
            }

            if (isVerbose) {
                utilsServer.logMsg(ELogMsgLevel.INFO, BEGIN_END_OF_DATA);
            }
            // Start of 'On End of Data' code snippet.
            // ToDo: Enter code that executes when all the input data is received by the transformation here
            // 
            // logInfo("The number of null rows for this partition is : " + partCountNullRows);
            // synchronized(lock)
            // {
            //        logInfo("The total number of null rows across partitions till now is : " +  countNullRows);
            // }


            //cacheClient.close();
            String processIdAndHost = ManagementFactory.getRuntimeMXBean().getName();
            logInfo("Client info:" + processIdAndHost);
            logInfo("Client Loader:" + this.getClass().getClassLoader().toString());
            // End of 'On End of Data' code snippet.
            if (isFatalExceptionThrown) {
                throw new JTXFatalException(fatalMsg);
            }
            if (isVerbose) {
                utilsServer.logMsg(ELogMsgLevel.INFO, EXIT_END_OF_DATA);
            }
        } catch (SDKException e) {
            handleException(e);
        }
    }

    /**
     * This function is called by PowerCenter engine when there is a transaction
     * notification. This function will be called only if Java Transformation
     * has the 'Transformation Scope' set to 'transaction'.
     *
     * @param transType one of COMMIT or ROLLBACK.
     */
    public void inputTransaction(int transType) throws SDKException {
        try {
            flushBuf();
            outputBuf = (IOutputBuffer) getOutputBuffers().get(0);
        } catch (SDKException e) {
            handleException(e);
        }
    }

    /**
     * This is a callable API and is not called by PowerCenter engine. This
     * function is called by user to generate an output row in 'On Input Row',
     * 'On Transactaction' and 'On End of Data' snippets for an active
     * transformation.
     */
    private void generateRow() throws SDKException {
        if (!isGenRowCall) {
            throw new JTXFatalException(INVALID_API_CALL_PASSIVE.toString());
        }
        if (isOutFldProjected("DESC") && (!isSetNullCalled("DESC"))) {
            if (DESC == null) {
                outputBuf.setNull(outRowNum, 0);
            } else {
                try {
                    outputBuf.setString(outRowNum, 0, DESC);
                } catch (DataTruncatedException e) {
                    handleDataTruncatedException("DESC");
                }
            }
        }


        incrementOutputRowNumber();
        clearNullColSet();
    }
}